package com.linjiang;

import javax.servlet.Servlet;
import javax.servlet.ServletException;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;

/**
 * socket处理器
 */
public class SocketProcessor implements Runnable{
    public SocketProcessor(Socket socket, Tomcat tomcat) {
        this.socket = socket;
        this.tomcat = tomcat;
    }

    public Socket getSocket() {
        return socket;
    }

    private Socket socket;

    private Tomcat tomcat;

    @Override
    public void run() {
        processSocket(socket);
    }

    /**
     * 处理socket连接 读数据和写数据
     * @param socket
     */
    private void processSocket(Socket socket) {
        System.out.println("开始处理");
        try {
            InputStream inputStream = socket.getInputStream();
            byte[] bytes = new byte[1024];//读取1kb的数据
            inputStream.read(bytes);

            //解析字节流
            // 解析字节流，遇到⼀个空格就退出
            int pos = 0;
            int begin = 0, end = 0;
            for (; pos < bytes.length; pos++, end++) {
                if (bytes[pos] == ' ') break;
            }
            // 组合空格之前的字节流，转换成字符串就是请求⽅法
            StringBuilder method = new StringBuilder();
            for (; begin < end; begin++) {
                method.append((char) bytes[begin]);
            }
            System.out.println(method.toString());

            // 解析URL
            pos++;
            begin++;
            end++;
            for (; pos < bytes.length; pos++, end++) {
                if (bytes[pos] == ' ') break;
            }
            StringBuilder url = new StringBuilder();
            for (; begin < end; begin++) {
                url.append((char) bytes[begin]);
            }
            System.out.println(url.toString());

            // 解析协议版本
            pos++;
            begin++;
            end++;
            for (; pos < bytes.length; pos++, end++) {
                if (bytes[pos] == '\r') break;
            }
            StringBuilder protocl = new StringBuilder();
            for (; begin < end; begin++) {
                protocl.append((char) bytes[begin]);
            }
            System.out.println(protocl.toString());

            //获得请求对象
            Request request = new Request(method.toString(), url.toString(), protocl.toString());
            //生成相应响应对象
            Response response = new Response(request, socket.getOutputStream());
            //针对请求的url匹配对应应用的Servlet执行对应逻辑
            String requestUrl = request.getRequestURL().toString();
            requestUrl = requestUrl.substring(1);//先把第一个斜杠去掉
            String[] parts = requestUrl.split("/");//按斜杠分隔
            String appName = parts[0];
            //根据应用名称，取出对应的servlet容器
            Context context = tomcat.getContextMap().get(appName);
            if (context != null){
                //根据请求路径匹配获取对应的servlet
                Servlet servlet = context.getUrlPattern(parts[1]);
                //执行处理逻辑
                servlet.service(request, response);
            }
            //发送响应
            response.complete();

        } catch (IOException | ServletException e) {
            //返回异常响应
            throw new RuntimeException(e);
        }

    }
}
